# @Time : 2024-10-15 18:12
# @Author : Fioman 
# @Phone : 13149920693

"""
统计Python代码的行数,目前是整个项目所有的代码行数统计,当然后期可以指定固定的目录的代码
"""

import os
from datetime import datetime

currentDir = os.path.dirname(os.path.abspath(__file__))
rootDir = os.path.dirname(currentDir)
recordFilePath = os.path.join(currentDir, "code_count_record.txt")

webFileDir = os.path.join(os.path.dirname(rootDir), r"src\\pages")

# 先创建统计代码统计的文件
try:
    f1 = open(recordFilePath, "r", encoding="utf-8")
    f1.close()
except IOError as e:
    f2 = open(recordFilePath, "w")

# 用来存放要统计的文件列表,目前只统计.py结尾的文件
pyEndFiles = []
# 用来存放要统计的文件列表,js文件或者是ts文件.
webFiles = []


def get_now_time_str():
    """
          获取当前的时间,格式为: 2024-10-16 11:03:04
    :return:
    """
    return datetime.now().strftime('%Y-%m-%d %H:%M:%S')


def count_time_offset(targetTime):
    """
    获取时间间隔,返回月份和天数还有小时,分
    :param targetTime:目标时间
    :return:
    """
    targetTime = datetime.strptime(targetTime, "%Y-%m-%d %H:%M:%S")
    timeDiff = datetime.now() - targetTime
    totalMonth = timeDiff.days // 30
    totalDays = timeDiff.days % 30
    totalHours = timeDiff.seconds // 3600
    totalMinutes = timeDiff.seconds % 3600 // 60
    timeDuration = f"{totalMonth} 月 {totalDays} 天 {totalHours} 小时 {totalMinutes} 分"

    return timeDuration


def count_code_lines(filePath):
    """
    统计这个文件中代码行数,注释行数,以及空格的行数
    :param filePath:要统计的文件路径
    :return:
    """
    blank, code, note = 0, 0, 0
    manyNoteFlag = False  # 多行注释标志位
    with open(filePath, "r", encoding="utf-8") as f:
        while True:
            line = f.readline()
            if not line:
                break
            if manyNoteFlag:
                note += 1
                # 多行注释包括两种一种是双引号 """ """  一种是单引号 ''' '''
                if line.strip().startswith('"""') or line.strip().startswith("'''") or line.strip().startswith("*/"):
                    manyNoteFlag = False
                continue
            if len(line.strip()) == 0:
                blank += 1
            elif line.strip().startswith("#") or line.strip().startswith("//"):
                note += 1
            elif line.strip().startswith('"""') or line.strip().startswith("'''") or line.strip().startswith("/*"):
                note += 1
                manyNoteFlag = True
            else:
                code += 1
    return blank, code, note


def get_last_count_record(lastRecordLine):
    """
    根据最后一行记录解析最后一条记录的信息
    :param lastRecordLine:
    :return:
    """
    lineSplit = lastRecordLine.strip().split(":")
    code = int(lineSplit[3].split(",")[0])
    note = int(lineSplit[4].split(",")[0])
    blank = int(lineSplit[5].split(",")[0])
    return code, note, blank


if __name__ == '__main__':
    currentFileName = os.path.split(__file__)[1]
    for root, dirs, files in os.walk(rootDir):
        for file in files:
            if not file.endswith(".py") or file == "__init__.py" or file == currentFileName:
                continue
            pyEndFiles.append(os.path.join(root, file))

    for root, dirs, files in os.walk(webFileDir):
        for file in files:
            if not file.endswith((".js", "jsx", ".ts", "tsx")):
                continue
            webFiles.append(os.path.join(root, file))
    totalFiles = pyEndFiles + webFiles

    allBlank, allCode, allNote = 0, 0, 0
    for filePathOuter in totalFiles:
        parentDir, fileName = os.path.split(filePathOuter)
        parentDirName = os.path.split(parentDir)[1]
        # 加上最近的目录,便于区分是哪个目录下的文件
        fileNameWithDir = os.path.join(parentDirName, fileName)
        blankOuter, codeOuter, noteOuter = count_code_lines(filePathOuter)
        allBlank += blankOuter
        allCode += codeOuter
        allNote += noteOuter
        print(f"文件 {fileNameWithDir} 统计结果 代码: {codeOuter},注释:{noteOuter},空白:{blankOuter},"
              f"总共:{blankOuter + codeOuter + noteOuter}")
    print(f"整个项目统计结果 代码: {allCode},注释: {allNote},空白: {allBlank},"
          f"总共: {allBlank + allCode + allNote}")

    with open(recordFilePath, "r", encoding="utf-8") as f:
        lines = f.readlines()
        lastRecordTime = get_now_time_str()
        if len(lines) == 0:
            allCodeAdded = allCode
            allBlankAdded = allBlank
            allNoteAdded = allNote
        else:
            lastCode, lastNote, lastBlank = get_last_count_record(lines[-1])
            allCodeAdded = allCode - lastCode
            allBlankAdded = allBlank - lastBlank
            allNoteAdded = allNote - lastNote
            lastLineContent = lines[-1].strip().split(" ")
            lastRecordTime = lastLineContent[0] + " " + lastLineContent[1]
        timeOffset = count_time_offset(lastRecordTime)

    with open(recordFilePath, 'a', encoding='utf-8') as fOuter:
        fOuter.write("\n\n" + get_now_time_str() + f" 项目统计结果 代码: {allCode},注释: {allNote},"
                                                   f"空白: {allBlank},增加: 代码 {allCodeAdded},注释 {allNoteAdded},"
                                                   f"空白 {allBlankAdded},距离上次统计:{timeOffset} ")
